﻿using Marmat.Forms;
using Marmat.Foundation;
using Marmat.FrameWork;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Marmat.Template.WinForm
{
    public class AdvRelationControlImplement<Entity> : IProvider
    {
        private readonly AdvRelationControl dropDown;
        private IAdvRelationProvider<Entity> relationProvider;

        /// <summary>
        /// 生成列集合触发的委托。
        /// </summary>
        [DefaultValue(null)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Action<SelectionRecordColumn> ColumnBuilder { get; set; }

        internal AdvRelationControlImplement(AdvRelationControl dropDown)
        {
            this.dropDown = dropDown;
            relationProvider = SystemCommand.GetService<IAdvRelationProvider<Entity>>();
            dropDown.ShowDropDownButton = false;
            dropDown.TextEditStyle = TextEditStyles.DisableTextEditor;
            dropDown.ModalButtonClick += this.DropDown_ModalButtonClick;
            dropDown.ValueChanged += this.DropDown_ValueChanged;
        }

        private void DropDown_ValueChanged(object sender, EventArgs e)
        {
            if (!dropDown.DesignMode && dropDown.DataSource is null && !string.IsNullOrEmpty(dropDown.Value))
            {
                dropDown.ValueMember = relationProvider.PrimaryName;
                dropDown.DisplayMember = relationProvider.DisplayName;
                dropDown.DataSource = new[] { relationProvider.Load(dropDown.Value) };
            }
        }

        private void DropDown_ModalButtonClick(object sender, EventArgs e)
        {
            var recordForm = SystemCommand.GetService<ISelectionRecordPaginationForm<Entity>>();

            var provider = this.relationProvider;
            recordForm.ColumnBuilder = this.ColumnBuilder;
            recordForm.Search = (args) =>
            {
                string condition = args.Filter;
                if (!string.IsNullOrEmpty(condition) && !string.IsNullOrEmpty(this.dropDown.Filter))
                    condition = $"({this.dropDown.Filter}) And ({condition})";
                else if (!string.IsNullOrEmpty(this.dropDown.Filter))
                    condition = this.dropDown.Filter;
                var result = provider.Load(condition, args.LoadPage, recordForm.LoadTop, string.Empty, out int totalCount);
                args.TotalCount = totalCount;
                return result;
            };
            if (recordForm.ShowDialog(out var item))
            {
                dropDown.ValueMember = provider.PrimaryName;
                dropDown.DisplayMember = provider.DisplayName;
                dropDown.DataSource = new[] { item };

                if (item is DataRow dataRow)
                {
                    dropDown.Value = dataRow[provider.PrimaryName]?.ToString();
                }
                else
                {
                    var member = item.GetType().GetMembers().Where(x => (x is FieldInfo || x is PropertyInfo) && x.Name == provider.PrimaryName).FirstOrDefault();
                    if (member is FieldInfo field)
                        dropDown.Value = field.GetValue(item)?.ToString();
                    else if (member is PropertyInfo property)
                        dropDown.Value = property.GetValue(item)?.ToString();

                    if (dropDown.BindingField.DataSource != null && !string.IsNullOrEmpty(dropDown.BindingField.DataMember))
                        dropDown.BindingField.WriteValue();
                }
            }
        }
    }
}